package com.alogic.remote.xscript.request;

import com.alogic.remote.HttpConstants;
import com.alogic.remote.Request;
import com.alogic.remote.xscript.RequestHandler;
import com.alogic.xscript.AbstractLogiclet;
import com.alogic.xscript.ExecuteWatcher;
import com.alogic.xscript.Logiclet;
import com.alogic.xscript.LogicletContext;
import com.alogic.xscript.doc.XsObject;
import com.anysoft.util.*;
import org.apache.commons.lang3.StringUtils;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import java.util.ArrayList;
import java.util.List;

/**
 * 动态Form实现
 *
 * @since 1.6.13.26 [20201114 duanyy] <br>
 */
public class ByForm2 extends RequestHandler {

    /**
     * 子节点
     */
    protected List<Logiclet> children = new ArrayList<Logiclet>(); // NOSONAR

    protected String cid = "$form-builder";

    protected String encoding = "utf-8";

    public ByForm2(String tag, Logiclet p) {
        super(tag, p);
        registerModule("field",Field.class);
    }

    @Override
    public void configure(Properties props){
        super.configure(props);
        cid = PropertiesConstants.getString(props,"cid",cid);
        encoding = PropertiesConstants.getString(props,"encoding",encoding,true);
    }

    @Override
    public void configure(Element element, Properties props) {
        XmlElementProperties p = new XmlElementProperties(element, props);
        NodeList nodeList = element.getChildNodes();

        for (int i = 0 ; i < nodeList.getLength() ; i ++){
            Node n = nodeList.item(i);

            if (n.getNodeType() != Node.ELEMENT_NODE){
                //只处理Element节点
                continue;
            }

            Element e = (Element)n;
            String xmlTag = e.getNodeName();
            Logiclet statement = createLogiclet(xmlTag, this);

            if (statement != null){
                statement.configure(e, p);
                children.add(statement);
            }
        }

        configure(p);
    }

    @Override
    protected void onExecute(final Request req, final XsObject root, final XsObject current, final LogicletContext ctx,
                             final ExecuteWatcher watcher) {
        req.setHeader(HttpConstants.CONTENT_TYPE, "application/x-www-form-urlencoded");

        FormBuilder builder = new FormBuilder();
        try {
            ctx.setObject(cid,builder);
            for (Logiclet child:children){
                child.execute(root, current, ctx, watcher);
            }
            req.setBody(builder.build(encoding));
        }finally {
            ctx.removeObject(cid);
        }
    }

    /**
     * 参数
     */
    public static class Field extends AbstractLogiclet {
        protected String $id;
        protected String $value;

        protected String pid = "$form-builder";

        public Field(String tag, Logiclet p) {
            super(tag, p);
        }

        @Override
        public void configure(Properties p) {
            super.configure(p);
            $id = PropertiesConstants.getRaw(p, "id", "");
            $value = PropertiesConstants.getRaw(p, "value", "");
            pid = PropertiesConstants.getString(p, "pid", pid, true);
        }

        @Override
        protected void onExecute(final XsObject root, final XsObject current, final LogicletContext ctx,
                                 final ExecuteWatcher watcher) {
            FormBuilder builder = ctx.getObject(pid);
            if (builder != null) {
                String id = PropertiesConstants.transform(ctx, $id, "");
                String value = PropertiesConstants.transform(ctx, $value, "");
                if (StringUtils.isNotEmpty(id)) {
                    builder.addParameters(id, value);
                }
            }
        }
    }
}
